#ifndef OCTREE_H
#define OCTREE_H

#include <vector>

class octnode;

class Octree
{
public:
	Octree(int _size = 8);
	~Octree();

	void SetVolume(int state, int x1, int y1, int z1, int x2, int y2, int z2);
	void Render();
	void Print();

private:
	octnode* root;
	int size;
};


class octnode
{
public:
	octnode(){};
	virtual ~octnode(){}
	
	virtual octnode* SetVolume(int state, int _x1, int _y1, int _z1, int _x2, int _y2, int _z2, int tabdepth) = 0;
	virtual void Render() = 0;
	virtual void Print(int tab) = 0;

protected:
	int x1, y1, z1;
	int x2, y2, z2;
};

class octbranch : public octnode
{
public:
	octbranch(int _x1, int _y1, int _z1, int _x2, int _y2, int _z2);
	~octbranch();

	octnode* SetVolume(int state, int _x1, int _y1, int _z1, int _x2, int _y2, int _z2, int tabdepth);
	void Render();
	void Print(int tab);

private:
	friend class octleaffilled;
	friend class octleafempty;
	octnode* child[8];
};

class octleaffilled : public octnode
{
public:
	octleaffilled(int _x1, int _y1, int _z1, int _x2, int _y2, int _z2);
	~octleaffilled();

	octnode* SetVolume(int state, int _x1, int _y1, int _z1, int _x2, int _y2, int _z2, int tabdepth);
	void Render();
	void Print(int tab);

private:
	bool neighborfilledp[6];
};

class octleafempty : public octnode
{
public:
	octleafempty(int _x1, int _y1, int _z1, int _x2, int _y2, int _z2);
	~octleafempty();

	octnode* SetVolume(int state, int _x1, int _y1, int _z1, int _x2, int _y2, int _z2, int tabdepth);
	void Render();
	void Print(int tab);

private:
	//vector<entity*> entities;
};

#endif

